﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

//初始化列表
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//		//初始化列表初始化
//		:_year(year)
//		,_month(month)
//		,_day(day)
//	{
//		//函数体内初始化
//		//_year = year;
//		//_month = month;
//		//_day = day;
//	}
//
//private:
//	//声明
//	int _year; 
//	int _month;
//	int _day;
//};

//初始化列表: 成员变量不显示写在初始化列表也会走初始化列表，
// 对于内置类型成员变量
//1.有缺省值就用缺省值的内容
//2.没有缺省值，有开始是随机值或者0，取决于编译器，所以建议加上缺省值
// 对于自定义类型成员变量，会去调用它自己的默认构造函数，如果没有那么就会编译报错
//typedef int StackDateType;
//class Stack
//{
//public:
//	Stack(int n = 4)
//		//初始化列表的顺序是按成员变量声明的顺序走的
//		//显示的在初始化列表初始化的成员变量会用显示写的值进行初始化
//		:_a((StackDateType*)malloc(sizeof(StackDateType)* n))
//		, _capacity(n)
//	{
//		if (_a == nullptr)
//		{
//			//....
//		}
//	}
//
//private:
//	StackDateType* _a;
//	int _top = 0; //缺省参数, C++11特效，成员变量声明时给予缺省参数
//	int _capacity;
//};
//
//int main()
//{
//	Date d;
//
//	Stack s;
//
//	return 0;
//}

//class Time
//{
//public:
//	Time(int hour)
//		:_hour(hour)
//	{
//
//	}
//
//private:
//	int _hour;
//};
//
//class Date
//{
//public:
//	Date(int& a, int year = 1, int month = 1, int day = 1)
//		//定义
//		:_year(year)
//		, _month(month)
//		, _day(day)
//		//对于引用、const修饰的成员变量、类类型成员变量都只能在初始化列表进行初始化
//		,_b(a)
//		,_i(10)
//		,_t(4)
//	{
//
//	}
//
//private:
//	//声明
//	int _year;
//	int _month;
//	int _day;
//	int& _b;
//	const int _i;
//	Time _t;
//};
//
//int main()
//{
//	int aa;
//	Date d(aa);
//
//	return 0;
//}

//类型转换
//class A
//{
//public:
//	A(int aa = 1)
//		:_aa1(aa)
//	{
//		cout << "A(int aa)" << endl;
//	}
//
//	A(int aa1, int aa2)
//		:_aa1(aa1)
//		, _aa2(aa2)
//	{
//
//	}
//
//	//拷贝构造本质上也是一个特殊的构造
//	//所以也能用初始化列表
//	A(const A& a)
//		:_aa1(a._aa1)
//	{
//		cout << "A(const A& a)" << endl;
//	}
//
//private:
//	int _aa1;
//	int _aa2;
//};
//
//class B
//{
//public:
//	B(A& aa)
//		:_a1(aa)
//	{
//
//	}
//
//private:
//	A _a1;
//};
//
//
//int main()
//{
//	//整数与类类型之间的隐式类型转换
//	//构造+拷贝构造->编译器会优化为直接构造
//	//先将整数1构造一个临时A类的对象，再用这个临时对象进行拷贝构造给aa1
//	A aa1 = 1;
//
//	//不同类类型之间的隐式类型转换
//	B b1 = aa1;
//
//	//C++11之后支持多参数的隐式类型转换
//	A aa2 = { 2,2 };
//
//	return 0;
//}

//static成员变量和static成员函数
//static成员变量不属于某个对象，是属于这个类的所有对象的
//class A
//{
//public:
//	//由于static成员变量不属于某个对象且static成员是存储在静态区的，所以不能走构造函数
//	//基本就是static成员变量只能在类内声明类外定义初始化
//	A(int a = 0)
//		:_a(a)
//	{
//
//	}
//
//	//静态成员函数
//	//1.特点是没有this指针
//	static void func()
//	{
//		//2.静态成员函数可以访问静态成员变量，但不能访问非静态成员变量因为没有this指针
//		//cout << _a << endl;//err
//		cout << _i << endl;
//	}
//
//	//3.非静态成员函数既可以访问静态成员变量也可以访问非静态成员变量
//	int func2()
//	{
//		cout << _a << endl;
//		cout << _i << endl;
//	}
//
//private:
//	int _a;
//	//静态成员变量的声明
//	static int _i;
//};
//
////static成员变量类外定义初始化
//int A::_i = 0;
//
//int main()
//{
//	A a;
//
//	return 0;
//}

//实现⼀个类，计算程序中创建出了多少个类对象?
//class A
//{
//public:
//	A(int a = 0)
//		:_a(a)
//	{
//		_count++;
//	}
//
//	static int GetCount()
//	{
//		return _count;
//	}
//
//private:
//	int _a;
//	static int _count;
//};
//
//int A::_count = 0;
//
//int main()
//{
//	A a1;
//	A a2;
//	A a3;
//
//	//用现有的对象访问
//	cout << a3.GetCount() << endl;
//	//指定类域访问
//	cout << A::GetCount() << endl;
//
//	return 0;
//}

// class Sum
// {
// public:
//     Sum()
//     {
//         _ret += _i;
//         _i += 1;
//     }

//     static int GetRet()
//     {
//         return _ret;
//     }

// private:
//     static int _ret;
//     static int _i;
// };

// int Sum::_i = 1;
// int Sum::_ret = 0;

// class Solution {
// public:
//     int Sum_Solution(int n) {
//         Sum s[n];

//         return Sum::GetRet();
//     }
// };

//JZ64 求1+2+3+...+n
//class Sum
//{
//public:
//    Sum()
//    {
//        _ret += _i;
//        _i += 1;
//    }
//
//    static int GetRet()
//    {
//        return _ret;
//    }
//
//private:
//    static int _ret;
//    static int _i;
//};
//
//int Sum::_i = 1;
//int Sum::_ret = 0;
//
//class Solution {
//public:
//    int Sum_Solution(int n) {
//        new Sum[n];
//
//        return Sum::GetRet();
//    }
//};

//友元
//class A
//{
//	//友元函数
//	friend void func(A& a);
//	//友元类
//	friend class B;
//public:
//	A(int aa = 1)
//		:_aa(aa)
//	{
//
//	}
//
//private:
//	int _aa;
//};
//
////func函数是A类的友元，所以func函数可以访问A类的成员变量
//void func(A& a)
//{
//	cout << a._aa << endl;
//}
//
//class B
//{
//	friend class C;
//
//public:
//	B(int b)
//		:_b(b)
//	{
//
//	}
//
//	//B是A的友元，所以B类可以访问A类私有的成员
//	//但友元是单向的，B是A的友元，B类可以访问A类私有的成员但A不能访问B的私有的成员
//	void func()
//	{
//		A aa1;
//		cout << aa1._aa << endl;
//		cout << _b << endl;
//	}
//
//private:
//	int _b;
//};
//
//class C
//{
//public:
//	C(int cc = 1)
//		:_c(cc)
//	{
//
//	}
//
//	void func()
//	{
//		//友元是不能传递的，
//		// 比如B是A的友元，C是B的友元，C可以访问B的成员，但不能访问A的成员
//		A a1;
//		//cout << a1._aa << endl;//err
//	}
//
//private:
//	int _c;
//};

//内部类
//1.内部类和外部类都是独立的类，只是内部类受访问限定符限制而已
//class A
//{
//public:
//	A(int a = 1)
//		:_aa(a)
//	{}
//
//
//private:
//	class B
//	{
//	public:
//		B(int b = 0)
//			:_b(b)
//		{}
//
//		//2.内部类天生就是外部类的友元,比如B天生就是A的友元
//		void func()
//		{
//			A a1;
//			cout << a1._aa << endl;
//			cout << _b << endl;
//		}
//
//	private:
//		int _b;
//	};
//
//private:
//	int _aa;
//};
//
//int main()
//{
//	A a;
//	//3.内部类受访问限定符限制
//	A::B b;//err
//
//	return 0;
//}

//JZ64 求1+2+3+...+n
//用内部类优化
/*class Solution {
    class Sum
    {
    public:
        Sum()
        {
            _ret += _i;
            _i += 1;
        }

    };

public:
    int Sum_Solution(int n) {
        new Sum[n];

        return _ret;
    }

private:
    static int _ret;
    static int _i;
};

int Solution::_i = 1;
int Solution::_ret = 0;*/

//匿名对象
//class A
//{
//public:
//    A(int a = 0)
//        :_aa(a)
//    { 
//        cout << "A(int a = 0)" << endl;
//    }
//
//    ~A()
//    {
//        cout << "~A()" << endl;
//    }
//
//private:
//    int _aa;
//};
//
//class B
//{
//public:
//    B(A aa)
//        :_aa(aa)
//    {
//
//    }
//
//private:
//    A _aa;
//};
//
//int main()
//{
//    //现有对象初始化
//    A aa1;
//    B b1(aa1);
//    cout << endl;
//    cout << endl;
//
//    //匿名对象初始化
//    //特点：
//    //1.匿名对象的生命周期只在这一行，用完就调用析构
//    B b2(A(1));
//    cout << endl;
//    cout << endl;
//
//    //隐式类型转换初始化
//    B b3(1);
//
//    return 0;
//}

//对象拷⻉时的编译器优化
//class A
//{
//public:
//    A(int a = 0)
//        :_aa(a)
//    { 
//        cout << "A(int a = 0)" << endl;
//    }
//
//    A(const A& a)
//    {
//        cout << "A(const A& a)" << endl;
//    }
//
//    A& operator=(const A& a)
//    {
//        cout << "A operator=(const A& a)" << endl;
//    }
//
//    ~A()
//    {
//        cout << "~A()" << endl;
//    }
//
//private:
//    int _aa;
//};
//
//A func()
//{
//    A aa;
//    return aa;
//}
//
//void func1(A aa)
//{ }
//
//int main()
//{
//    //构造+拷贝构造->优化为直接构造
//    A aa1 = 1;
//
//    cout << endl;
//    cout << endl;
//
//    //构造+拷贝构造->优化为直接构造
//    func();
//
//    cout << endl;
//    cout << endl;
//
//    //构造+拷贝构造+拷贝构造->优化为直接构造
//    A aa2 = func();
//
//    cout << endl;
//    cout << endl;
//
//    //构造+拷贝构造->构造
//    func1(1);
//
//    cout << endl;
//    cout << endl;
//
//    return 0;
//}

//C++内存管理方式

//int main()
//{
//    //开辟一个int类型的空间
//    int* ptr1 = new int;
//    //开辟一个int类型的空间并初始化为10
//    int* ptr2 = new int(10);
//
//    //开辟一个int类型的数组
//    int* ptr3 = new int[10];
//
//    //开辟一个int类型的数组并初始化前4个元素，后续的元素类似数组会初始化为0
//    int* ptr4 = new int[10] {1,2,3,4};
//
//    //释放内存
//    delete ptr1;
//    delete ptr2;
//
//    delete[] ptr3;
//    delete[] ptr4;
//
//
//    return 0;
//}

class A
{
public:
    A(int a = 1)
        :_a(a)
    {
        cout << "A()" << endl;
    }

    ~A()
    {
        cout << "~A()" << endl;
    }

private:
    int _a;
};

int main()
{
    //new和delete与malloc/calloc/realloc的区别是
    //1.对于内置类型几乎一样
    //2.对于自定义类型：
    //new会开空间并且调用构造函数进行初始化
    //delete会调用析构函数
    A* a = new A(10);

    delete a;

    return 0;
}